﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ComponentModel;
using System.Runtime.Serialization;

namespace ServerNodeLib
{
	/// <summary>
	/// This class is used to encapsulate specific actions for the 
	/// client node to complete.
	/// 
	/// Note that these actions are different than arbitrary commands
	/// send in BatchInfo.  These are actions like "getting next batch"
	/// or "change name."  Theey are specific to the client node.
	/// </summary>
	[DataContract()]
	public class ActionRequest
	{
		public ActionRequest()
			:this( ActionRequestType.NoAction)
		{
		}
		public ActionRequest(ActionRequestType actionType)
			: this(actionType, String.Empty, String.Empty)
		{
		}
		public ActionRequest(ActionRequestType actionType, String payloadKey, String payloadValue)
		{
			this.ActionType = actionType;
			this.payloadValue = payloadValue;
			this.payloadKey = payloadKey;
			this.ActionReqId = Guid.NewGuid();
			this.AddTime = DateTime.Now;
		}
		/// <summary>
		/// Defines the specific action the client should complete.
		/// </summary>
		[DataMember()]
		[DefaultValue(ActionRequestType.Error)]
		public ActionRequestType ActionType
		{
			get
			{
				return this.myActionType;
			}
			set
			{
				this.myActionType = value;
			}
		}
		private ActionRequestType myActionType;

		/// <summary>
		/// Provides supplmental information to the client
		/// that may be necessary to complete the action.
		/// 
		/// This information is serialized as a String to avoid
		/// WCF serialization issues.
		/// 
		/// For instance, the change name command would be accompanied
		/// by the new name.
		/// </summary>
		[DataMember()]
		[DefaultValue("")]
		public String PayloadValue
		{
			get
			{
				return this.payloadValue;
			}
			set
			{
				this.payloadValue = value;
			}
		}
		private String payloadValue;

		/// <summary>
		/// A key used to identify the payload or its destination.
		/// </summary>
		[DataMember()]
		[DefaultValue("")]
		public String PayloadKey
		{
			get
			{
				return this.payloadKey;
			}
			set
			{
				this.payloadKey = value;
			}
		}
		private String payloadKey;

		public override string ToString()
		{
			return ActionType.ToString();
		}
		/// <summary>
		/// Row guid for uniquely finding in persistent database
		/// </summary>
		public Guid ActionReqId;
		/// <summary>
		/// The time the server added the request to the queue
		/// This is so we can sort the requests and keep them in order
		/// </summary>
		public DateTime AddTime;
	}

	[DataContract()]
	public enum ActionRequestType
	{
		/// <summary>
		/// There was some random error that the server could not recover.
		/// </summary>
		[EnumMember()]
		Error=-1,
		/// <summary>
		/// Client is requested to do nothing
		/// </summary>
		[EnumMember()]
		NoAction=0,
		/// <summary>
		/// Requests the client to announce itself.
		/// The server cannot issue an action without the announcement.
		/// </summary>
		[EnumMember()]
		AnnounceNode=1,
		/// <summary>
		/// Provides the server with a new name
		/// The payload is the new name.
		/// </summary>
		[EnumMember()]
		ChangeSetting = 2,
		/// <summary>
		/// Requests the client to download the next job
		/// </summary>
		[EnumMember()]
		GetJob=5,
		/// <summary>
		/// Requests the client to kill its current job.
		/// The payload is the batch id the server thinks it's killing
		/// </summary>
		[EnumMember()]
		KillJob=10,
		/// <summary>
		/// Requests the client to reset its result queue (reset all the status to try to send again)
		/// </summary>
		[EnumMember()]
		ResetResultQueue = 15,
		/// <summary>
		/// Requests the client to resend the queue.
		/// The payload is the batch id
		/// </summary>
		[EnumMember()]
		SendResultQueue = 16,
		/// <summary>
		/// The server acknowledges receipt of the result
		/// The payload is the  batch id
		/// </summary>
		[EnumMember()]
		ResultAccpeted = 17,
	}
}
